package com.yanqu.road.dataHelper.action.excel;

import com.yanqu.road.dataHelper.gameServer.GameServer;
import com.yanqu.road.dataHelper.manager.DataMgr;
import com.yanqu.road.dataHelper.repair.BaseRepair;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author xx
 * @Date 2020/11/11
 */
public class Retained extends BaseRepair {

    public Retained(GameServer gameServer) {
        super(gameServer);
    }

    @Override
    public void repair(long param1, String param2) {

    }

    private List<Integer> retainedList = new ArrayList<>();

    private Map<Long,Map<String,Long>> rechargeMap = new ConcurrentHashMap<>();

    //date  "0""1" recharge userCount
    private Map<String,Map<String,Map<String,String>>> unionRechargeMap = new ConcurrentHashMap<>();

    //去重计算总用户数
    private Map<String,List<Long>> unionUserMap = new ConcurrentHashMap<>();
    private Map<String,List<Long>> noUnionUserMap = new ConcurrentHashMap<>();

    //每日注册人数
    private Map<String,Long> dateRegisterUser = new ConcurrentHashMap<>();

    public void go(String date){
        retainedList.add(1);
        retainedList.add(3);
        retainedList.add(7);
        retainedList.add(15);
        retainedList.add(30);
        retainedList.add(60);
        retainedList.add(90);
        //日期，是否加入商会
        Map<String,Map<String,Map<String, String>>> dataMap = new ConcurrentHashMap<>();
        String newDate = date;
        while (timeToStamp(newDate) < System.currentTimeMillis()){
            dataMap.put(newDate,makeDayDate(newDate));
            newDate = addDay(newDate,1);
        }

        getRecharge(date);
        getLoginUserCount(date);
        getLoginUserUnion(date);
        for(Integer day : retainedList){
            dataMap = getLog(dataMap,day,date);
        }

        List<Map<String, String>> listMap = new ArrayList<>();
        for(String dataDate : dataMap.keySet()){
            Map<String,Map<String, String>> tempData = dataMap.get(dataDate);
            for(Map<String,String> tempMap : tempData.values()){
                BigDecimal payCount = new BigDecimal(tempMap.get("付费总金额"));
                BigDecimal userCount = BigDecimal.ZERO;
                if(dateRegisterUser.containsKey(dataDate)){
                    userCount = BigDecimal.valueOf(dateRegisterUser.get(dataDate));
                    tempMap.put("总用户数",userCount.toString());
                }
                if("0".equals(tempMap.get("是否加入商会"))){
                    if(noUnionUserMap.containsKey(dataDate)){
                        tempMap.put("用户数",String.valueOf(noUnionUserMap.get(dataDate).size()));
                    }
                }else{
                    if(unionUserMap.containsKey(dataDate)){
                        tempMap.put("用户数",String.valueOf(unionUserMap.get(dataDate).size()));
                    }
                }

                if(userCount.compareTo(BigDecimal.ZERO) != 0){
                    tempMap.put("付费ARPPU",payCount.divide(userCount,4, BigDecimal.ROUND_UP).toString());
                    /*for(Integer day : retainedList){
                        BigDecimal tempUser = new BigDecimal(tempMap.get(day+"日留存"));
                        tempMap.put(day+"日留存",tempUser.divide(userCount,4, BigDecimal.ROUND_UP).toString());
                    }*/
                }else{
                    tempMap.put("付费ARPPU","0");
                }
                listMap.add(tempMap);
            }
        }
        DataMgr.addData(listMap);
    }

    public static Long timeToStamp(String timers){
        Date d = new Date();
        long timeStamp = 0;
        try {
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            d = sf.parse(timers);// 日期转换为时间戳
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        timeStamp = d.getTime();
        return timeStamp;
    }


    public static String addDay(String s, int n) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

            Calendar cd = Calendar.getInstance();
            cd.setTime(sdf.parse(s));
            cd.add(Calendar.DATE, n);//增加一天
            //cd.add(Calendar.MONTH, n);//增加一个月

            return sdf.format(cd.getTime());

        } catch (Exception e) {
            return null;
        }
    }

    //生成日期对应的默认数据
    private Map<String,Map<String,String>> makeDayDate(String date){
        Map<String,Map<String,String>> dateMap = new ConcurrentHashMap<>();
        Map<String,String> tempData = new ConcurrentHashMap<>();
        tempData.put("日期",date + "");
        tempData.put("区服id",getGameServer().getServerInfo().getServerId() + "");
        tempData.put("是否加入商会","0");
        tempData.put("总用户数","0");
        tempData.put("用户数","0");
        tempData.put("1日留存","0");
        tempData.put("3日留存","0");
        tempData.put("7日留存","0");
        tempData.put("15日留存","0");
        tempData.put("30日留存","0");
        tempData.put("60日留存","0");
        tempData.put("90日留存","0");
        tempData.put("付费用户数","0");
        tempData.put("付费ARPPU","0");
        tempData.put("付费总金额","0");
        dateMap.put("0",tempData);
        Map<String,String> tempData2 = new ConcurrentHashMap<>(tempData);
        tempData2.put("是否加入商会","1");
        dateMap.put("1",tempData2);
        return dateMap;
    }

    private Map<String,Map<String,Map<String,String>>> getLog(Map<String,Map<String,Map<String,String>>> dataMap,int day,String dateStart) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT uu.userId,FROM_UNIXTIME(registerTime,'%Y-%m-%d') as date,uu.vipExp,um.unionUid,um.quitTime,ll.ip FROM t_u_user uu" +
                " LEFT JOIN db_bussinessroad_log"+getGameServer().getServerInfo().getDbIndex()+".t_l_login ll on ll.userId = uu.userId AND TO_DAYS(ll.time) - ? = TO_DAYS(FROM_UNIXTIME(uu.registerTime,'%Y-%m-%d'))" +
                " LEFT JOIN t_u_union_member um on um.userId = uu.userId" +
                " WHERE FROM_UNIXTIME(uu.registerTime,'%Y-%m-%d') >= ? AND ll.ip IS NOT NULL" +
                " GROUP BY uu.userId";

        try {
            call = getGameServer().getConnection().prepareCall(sql);
            int i=1;
            call.setInt(i++,day);
            call.setString(i++,dateStart);
            rs = call.executeQuery();
            while (rs.next()) {
                long userId = rs.getLong("userId");
                String date = rs.getString("date");
                String unionUid = rs.getString("unionUid");
                String quitTime = rs.getString("quitTime");
                if(StringUtils.isNullOrEmpty(unionUid) && (StringUtils.isNullOrEmpty(quitTime) || "0".equals(quitTime))){
                    long userRetained = StringUtils.parseInt(dataMap.get(date).get("0").get(day+"日留存"));
                    dataMap.get(date).get("0").put(day+"日留存",String.valueOf(++userRetained));
                    if(unionRechargeMap.containsKey(date) && unionRechargeMap.get(date).containsKey("0")){
                        dataMap.get(date).get("0").put("付费用户数",unionRechargeMap.get(date).get("0").get("userCount"));
                        dataMap.get(date).get("0").put("付费总金额",unionRechargeMap.get(date).get("0").get("recharge"));
                        unionRechargeMap.get(date).remove("0");
                    }
                }else{
                    long userRetained = StringUtils.parseInt(dataMap.get(date).get("1").get(day+"日留存"));
                    dataMap.get(date).get("1").put(day+"日留存",String.valueOf(++userRetained));
                    if(unionRechargeMap.containsKey(date) && unionRechargeMap.get(date).containsKey("1")){
                        dataMap.get(date).get("1").put("付费用户数",unionRechargeMap.get(date).get("1").get("userCount"));
                        dataMap.get(date).get("1").put("付费总金额",unionRechargeMap.get(date).get("1").get("recharge"));
                        unionRechargeMap.get(date).remove("1");
                    }
                }
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
        return dataMap;
    }


    private void getRecharge(String dateStart) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "select sum(amount) as allRecharge,ur.userId,left(ur.createTime,10) as date,um.unionUid,um.quitTime " +
                " FROM t_u_recharge_detail ur " +
                " LEFT JOIN t_u_union_member um on um.userId = ur.userId" +
                " WHERE createTime >= ? AND (orderStatus = 1 or orderStatus = 2)" +
                " GROUP BY userId,left(createTime,10)";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            int i = 1;
            call.setString(i++,dateStart);
            rs = call.executeQuery();
            while (rs.next()) {
                long userId = rs.getLong("userId");
                String date = rs.getString("date");
                long allRecharge = rs.getLong("allRecharge");
                String unionUid = rs.getString("unionUid");
                String quitTime = rs.getString("quitTime");
                if(!rechargeMap.containsKey(userId)){
                    rechargeMap.put(userId,new ConcurrentHashMap<>());
                }
                rechargeMap.get(userId).put(date,allRecharge);
                if(!unionRechargeMap.containsKey(date)){
                    unionRechargeMap.put(date,new ConcurrentHashMap<>());
                }
                if(StringUtils.isNullOrEmpty(unionUid) && (StringUtils.isNullOrEmpty(quitTime) || "0".equals(quitTime))){
                    if(!unionRechargeMap.get(date).containsKey("0")){
                        unionRechargeMap.get(date).put("0",new ConcurrentHashMap<>());
                        unionRechargeMap.get(date).get("0").put("userCount","0");
                        unionRechargeMap.get(date).get("0").put("recharge","0");
                    }
                    Map<String,String> tempData = unionRechargeMap.get(date).get("0");
                    BigInteger userCount = new BigInteger(tempData.get("userCount"));
                    tempData.put("userCount",userCount.add(BigInteger.ONE).toString());
                    BigInteger recharge = new BigInteger(tempData.get("recharge"));
                    tempData.put("recharge",recharge.add(BigInteger.valueOf(allRecharge)).toString());
                }else{
                    if(!unionRechargeMap.get(date).containsKey("1")){
                        unionRechargeMap.get(date).put("1",new ConcurrentHashMap<>());
                        unionRechargeMap.get(date).get("1").put("userCount","0");
                        unionRechargeMap.get(date).get("1").put("recharge","0");
                    }
                    Map<String,String> tempData = unionRechargeMap.get(date).get("1");
                    BigInteger userCount = new BigInteger(tempData.get("userCount"));
                    tempData.put("userCount",userCount.add(BigInteger.ONE).toString());
                    BigInteger recharge = new BigInteger(tempData.get("recharge"));
                    tempData.put("recharge",recharge.add(BigInteger.valueOf(allRecharge)).toString());
                }
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }

        String sql2 = "select sum(amount) as allThirdRecharge,ut.userId,left(ut.createTime,10) as date,um.unionUid,um.quitTime " +
                " FROM t_u_thirdparty_recharge ut" +
                " LEFT JOIN t_u_union_member um on um.userId = ut.userId" +
                " WHERE createTime >= ? AND (orderStatus = 1 or orderStatus = 2)" +
                " GROUP BY userId,left(createTime,10)";
        try {
            call = getGameServer().getConnection().prepareCall(sql2);
            int i = 1;
            call.setString(i++,dateStart);
            rs = call.executeQuery();
            while (rs.next()) {
                long userId = rs.getLong("userId");
                String date = rs.getString("date");
                long allThirdRecharge = rs.getLong("allThirdRecharge");
                String unionUid = rs.getString("unionUid");
                String quitTime = rs.getString("quitTime");
                if(StringUtils.isNullOrEmpty(unionUid) && (StringUtils.isNullOrEmpty(quitTime) || "0".equals(quitTime))){
                    if(!unionRechargeMap.get(date).containsKey("0")){
                        unionRechargeMap.get(date).put("0",new ConcurrentHashMap<>());
                        unionRechargeMap.get(date).get("0").put("userCount","0");
                        unionRechargeMap.get(date).get("0").put("recharge","0");
                    }
                    Map<String,String> tempData = unionRechargeMap.get(date).get("0");
                    if(rechargeMap.containsKey(userId) && rechargeMap.get(userId).containsKey(date)){
                        BigInteger userCount = new BigInteger(tempData.get("userCount"));
                        tempData.put("userCount",userCount.add(BigInteger.ONE).toString());
                    }
                    BigInteger recharge = new BigInteger(tempData.get("recharge"));
                    tempData.put("recharge",recharge.add(BigInteger.valueOf(allThirdRecharge)).toString());
                }else{
                    if(!unionRechargeMap.get(date).containsKey("1")){
                        unionRechargeMap.get(date).put("1",new ConcurrentHashMap<>());
                        unionRechargeMap.get(date).get("1").put("userCount","0");
                        unionRechargeMap.get(date).get("1").put("recharge","0");
                    }
                    Map<String,String> tempData = unionRechargeMap.get(date).get("1");
                    if(rechargeMap.containsKey(userId) && rechargeMap.get(userId).containsKey(date)){
                        BigInteger userCount = new BigInteger(tempData.get("userCount"));
                        tempData.put("userCount",userCount.add(BigInteger.ONE).toString());
                    }
                    BigInteger recharge = new BigInteger(tempData.get("recharge"));
                    tempData.put("recharge",recharge.add(BigInteger.valueOf(allThirdRecharge)).toString());
                }
                if(!rechargeMap.containsKey(userId)){
                    rechargeMap.put(userId,new ConcurrentHashMap<>());
                    rechargeMap.get(userId).put(date,allThirdRecharge);
                }else{
                    if(rechargeMap.get(userId).containsKey(date)){
                        rechargeMap.get(userId).put(date,rechargeMap.get(userId).get(date) + allThirdRecharge);
                    }else{
                        rechargeMap.get(userId).put(date,allThirdRecharge);
                    }
                }
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
    }

    //每日注册人数
    private void getLoginUserCount(String dateStart) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT FROM_UNIXTIME(registerTime,'%Y-%m-%d') as date,COUNT(DISTINCT(userId)) as countUser FROM t_u_user " +
                "WHERE  FROM_UNIXTIME(registerTime,'%Y-%m-%d') >= ?" +
                "GROUP BY TO_DAYS(FROM_UNIXTIME(registerTime,'%Y-%m-%d'))";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            int i = 1;
            call.setString(i++,dateStart);
            rs = call.executeQuery();
            while (rs.next()) {
                long countUser = rs.getLong("countUser");
                String date = rs.getString("date");
                dateRegisterUser.put(date,countUser);
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
    }

    private void getLoginUserUnion(String dateStart) {
        ResultSet rs = null;
        CallableStatement call = null;
        String sql = "SELECT FROM_UNIXTIME(registerTime,'%Y-%m-%d') as date,uu.userId,um.unionUid,um.quitTime FROM t_u_user uu" +
                " LEFT JOIN t_u_union_member um on um.userId = uu.userId" +
                " WHERE  FROM_UNIXTIME(registerTime,'%Y-%m-%d') >= ?";
        try {
            call = getGameServer().getConnection().prepareCall(sql);
            int i = 1;
            call.setString(i++,dateStart);
            rs = call.executeQuery();
            while (rs.next()) {
                String date = rs.getString("date");
                long userId = rs.getLong("userId");
                String unionUid = rs.getString("unionUid");
                String quitTime = rs.getString("quitTime");
                if(StringUtils.isNullOrEmpty(unionUid) && (StringUtils.isNullOrEmpty(quitTime) || "0".equals(quitTime))){
                    if(!noUnionUserMap.containsKey(date)){
                        noUnionUserMap.put(date,new ArrayList<>());
                    }
                    noUnionUserMap.get(date).add(userId);
                }else{
                    if(!unionUserMap.containsKey(date)){
                        unionUserMap.put(date,new ArrayList<>());
                    }
                    unionUserMap.get(date).add(userId);
                }
            }
        } catch (SQLException ex) {
            getGameServer().getLogger().error("异常错误", ex);
        } finally {
            getGameServer().closeConnection(call, rs);
        }
    }
}
